package xmw

import (
	"bytes"
	"gitee.com/xiedongji/antgo/core"
	"gitee.com/xiedongji/antgo/cpts/xlog"
	"io"
	"time"

	"github.com/gin-gonic/gin"
)

/* ====================================================================== *
 * 功能:请求日志记录中间件 (RequestLogMiddleware)
 * 类型:中间件
 * 描述:记录日志
 * ====================================================================== */
func RequestLogMiddleware() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		requestInLog(ctx)
		defer requestOutLog(ctx)
		ctx.Next()
	}
}

// 入口 日志
func requestInLog(ctx *gin.Context) {
	traceCtx := core.NewTrace()
	if traceId := ctx.Request.Header.Get(core.TRACE_ID); traceId != "" {
		traceCtx.TraceId = traceId
	}

	if spanId := ctx.Request.Header.Get(core.SPAN_ID); spanId != "" {
		traceCtx.SpanId = spanId
	}

	ctx.Set("startExecTime", time.Now())
	ctx.Set(core.CTX_TRACE, traceCtx)

	bodyBytes, _ := io.ReadAll(ctx.Request.Body)                // 由于读取了Body之后,里面就被清空了
	ctx.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) // 因此我们需要将读取的内容又重新赋值给Body 回写

	// 记录日志
	xlog.Logger(core.AppLogName, "Request").Info().
		Str("uri", ctx.Request.RequestURI).
		Str("method", ctx.Request.Method).
		Any("args", ctx.Request.PostForm).
		Str("body", string(bodyBytes)).
		Str("from", ctx.ClientIP()).
		Msg("请求信息:")
}

// 出口 日志
func requestOutLog(ctx *gin.Context) {
	endExecTime := time.Now()
	st, _ := ctx.Get("startExecTime")
	startExecTime, _ := st.(time.Time)

	// 获取 ResponseXXXXX 中 设置的 ctx.SET(xctx.CTX_RESPONSE, xxxxxx)
	response, _ := ctx.Get(core.CTX_RESPONSE)
	// 获取链路追踪
	//trace, _ := ctx.Get(core.CTX_TRACE)
	//traceCtx, _ := trace.(*core.TraceContext)

	xlog.Logger(core.AppLogName, "Response").Info().
		Str("uri", ctx.Request.RequestURI).
		Str("method", ctx.Request.Method).
		Any("args", ctx.Request.PostForm).
		Str("from", ctx.ClientIP()).
		Any("response", response).
		Float64("proc_time", endExecTime.Sub(startExecTime).Seconds()).
		Msg("响应信息:")
}
